package Baseliner;

require 5.006;
$VERSION = '0.9';

use strict;
use Carp;
use Error qw(:try);
use YAML qw'Dump';

## load plugins
use Module::Pluggable search_path => [ 'Baseliner::Parse', 'Baseliner::Build', 'Baseliner::Test', 'Baseliner::Checkout'] , 
			require => 1;

my %Services;
my %ServiceablePlugins;

BEGIN {	
	my $loadstatus=1;
	foreach my $plugin ( plugins ) { ## seems to load them
		my $services = $plugin->services();
		if( ref $services ) {
			foreach my $service (  keys %$services ) {
				push @{ $ServiceablePlugins{$plugin} }, $service;
				$Services{$service}{plugin} = $plugin;
				foreach my $key ( keys %{ $$services{$service} } ) {
					if( $key eq 'config' ) {
						try {
							$Services{$service}{$key} = YAML::Tiny::Load($$services{$service}->{$key});
						} otherwise {
							print "Error: failed while loading '$service' config:\n".shift();
							$loadstatus=0;
						};
					} else {
						$Services{$service}{$key} = $$services{$service}->{$key};
					}
				}
			}
		}
		else {
			## no service, consider warning?
		}
	}; 

	$Baseliner::locale = 'es';

    if (0) { # SET THIS TO ZERO FOR TESTING AND RELEASES!
		$SIG{__DIE__ } = \&__carp_confess;
		$SIG{__WARN__} = \&__carp_confess;
    }
    sub __carp_confess { require Carp; Carp::confess(@_) }
    
    exit 1 if( !$loadstatus);  ## all errors at the end
}

## whatever I have to export, is here
use Exporter::Tidy default=>[ qw(bali $VERSION) ];

## start plugin funcs

sub service {
	my $service = shift;
	if( ref $Services{$service} ) {
		my $plugin = $Services{$service}{plugin};
		&{ $Services{ $service }{code} }( @_ );
	} else {
		print "Baseliner: service '$service' not found in any plugin."
			."\nServiceable plugins loaded:\n -".join "\n -",keys %ServiceablePlugins;
		print "\n";
	}
	return ();
}

sub usage {
	my $RET="";
	foreach my $service ( keys %Services ) {
		$RET.= $service."\n";
		if ( ref $Services{$service}{config} ) {
			my $config = $Services{$service}{config};
			my $task = join ' ', map { "-".join '=', split /\|/, $_ } map { $config->{task}{$_}{opt} } keys %{$config->{task}};
			$RET .= "\tbali $service ".$task." ".$config->{cmd}{line}."\n";
			$RET .= "\t".$config->{cmd}{desc}."\n";
		}
		else {
			$RET .= $Services{$service}{usage}."\n";
			$RET .= $Services{$service}{description}."\n";
		}
	}
	$RET =~ s/\n\n/\n/g; ## cleanup
	return $RET;
}

1;

__END__

=head1 SYNOPSIS

Baseliner runtime class with plugin loader.

=head1 USAGE

	use Baseliner;
	
	

=head1 TODO

* Bali - command-line interface scripts

* All the server and daemon stuff (as plugins to bali also):

	Baseliner::Server;


Some plugins I'd like to write:

	use Baseliner::Parse::EclipseWorkspace::J2EE;

	use Baseliner::Build::Ant;
	use Baseliner::Build::NAnt;

	use Baseliner::Checkout::SVN;
	use Baseliner::Checkout::CVS;
	use Baseliner::Checkout::Git;
	use Baseliner::Checkout::Bazaar;
	use Baseliner::Checkout::Harvest;
	use Baseliner::Checkout::Perforce;
	use Baseliner::Checkout::Clearcase;

	use Baseliner::Deploy::Tomcat;
	use Baseliner::Deploy::WAS::Script;
	use Baseliner::Deploy::WAS::DeploymentManager;
	use Baseliner::Deploy::Weblogic;

=cut